home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-11-17 | 19.1 KB | 531 lines | [TEXT/MPS ] |
- {–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
-
- PROJECT: Threads Traffic Simulation
-
- FILE: UDocument.p
-
- LANGUAGE: MPW Pascal (version 3.2)
-
- DESCRIPTION: All handling of document manipulation is done here. With this current
- document structure it should be easy to modify the program to support
- multiple documents at the same time.
-
- AUTHOR(S): William H. Knott
- Apple Computer
- Cupertino, CA 95014
- AppleLink : KNOTT
-
- VERSION(S): 1.0 14-Aug-92 WHK Brand New Today.
-
- –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––}
-
- UNIT UDocument;
-
- INTERFACE
-
- USES
- MemTypes, QuickDraw, OSIntf, ToolIntf, PackIntf, Traps,
-
- Threads,
-
- UApplication, USimulation, UEventMgmt;
-
-
- PROCEDURE Segment_UDocument;
- PROCEDURE InitDocumentGlobals;
- PROCEDURE CreateNewDocument;
- PROCEDURE CloseDocument(theWindow : WindowPtr);
- PROCEDURE CloseAllOpenDocuments;
- PROCEDURE HandleDocumentEvent(theWindow : WindowPtr; theEvent : EventRecord);
- FUNCTION IsWindowADocument(theWind : WindowPtr) : BOOLEAN;
- PROCEDURE DoPrintDocument(theWind : WindowPtr);
- PROCEDURE DoPageSetupDoc(theWind : WindowPtr);
-
- TYPE
- DocumentHdl = ^DocumentPtr; { This structure is provided in support of a multiple document }
- DocumentPtr = ^DocumentRec; { application. By bundling the documents global variable }
- DocumentRec = RECORD { it is easy to convert this program into a multiple doc app. }
- docWindow : WindowPtr;
- docHasData : BOOLEAN; { Lets us know whether the document has any data at all. }
- docIsDirty : BOOLEAN; { If data in doc has changed, this lets us know whether we need to save the document. }
- docHasName : BOOLEAN; { If the user has saved once or open a saved file, doc will have a name, else 'Untitled' }
- docName : Str32; { The name of the currently open document. Empty string means default. }
- END;
-
- VAR
- gDocument : DocumentHdl;
- gWindowSize : RECT;
-
- IMPLEMENTATION
-
- {$S Document}
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- { }
- { Segment_UDocument }
- { }
- { Provided as a convenient way of unloading the UDocument segment when needed }
- { }
- { July 15, 1992 WHK Created today }
- { }
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- PROCEDURE Segment_UDocument;
- BEGIN
- END;
-
- {$S Document}
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- { }
- { InitDocumentGlobals }
- { }
- { Initialize any variables used by document management when the application starts. }
- { }
- { July 15, 1992 WHK Created today }
- { }
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- PROCEDURE InitDocumentGlobals;
- BEGIN
- gDocument := NIL;
- END;
-
- {$S Document}
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- { }
- { CreateADocument }
- { }
- { Generates a new document and initializes a new traffic light into it. }
- { }
- { July 15, 1992 WHK Created today }
- { }
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- FUNCTION CreateADocument(docName : Str255;
- windSize : RECT) : DocumentHdl;
- VAR
- buildDocument : DocumentHdl;
- tempWind : WindowPtr;
- BEGIN
- CreateADocument := NIL;
- buildDocument := DocumentHdl(NewHandle(Sizeof(DocumentRec)));
- IF (buildDocument = NIL)THEN EXIT(CreateADocument);
-
- tempWind := GetNewWindow(kNewWindow,NIL,pointer(-1));
- IF (tempWind = NIL)THEN
- BEGIN
- DisposHandle(Handle(buildDocument));
- EXIT(CreateADocument);
- END;
-
- IF docName <> '' THEN
- SetWTitle(tempWind, docName);
-
- SizeWindow(tempWind,(windSize.right - windSize.left), (windSize.bottom - windSize.top),TRUE);
- MoveWindow(tempWind,windSize.left,windSize.top,TRUE);
- ShowWindow(tempWind);
-
- buildDocument^^.docWindow := tempWind;
- CreateADocument := buildDocument;
-
- gWindowSize := tempWind^.portRect;
-
- gIntoCooperativeWind := tempWind;
-
- InitializeRoadParams;
-
- CreateTrafficLight;
- END;
-
- {$S Document}
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- { }
- { CreateNewDocument }
- { }
- { The user had chosen the New command from the File menu, which means that we now }
- { want to create a new document. The current documentation structure for this }
- { application only allows for one open document at a time, so there should not be }
- { an already open document window when this routine is called. }
- { }
- { July 15, 1992 WHK Created today }
- { }
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- PROCEDURE CreateNewDocument;
- VAR
- windSize : RECT;
- BEGIN
- IF (gDocument <> NIL)THEN EXIT(CreateNewDocument);
-
- windSize := ScreenBits.bounds;
- InsetRect(windSize,5,5);
- windSize.top := windSize.top + 40;
-
- gDocument := CreateADocument('Threaded Traffic Simulation', windSize);
- IF (gDocument = NIL)THEN EXIT(CreateNewDocument);
- ShowWindow(gDocument^^.docWindow);
-
- SetMenuBarState;
- END;
-
- {$S Document}
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- { }
- { CloseDocument }
- { }
- { The user had chosen the Close command from the File menu, click in the windows }
- { close box, or Quit the application. It is here that we close the document, }
- { prompting the user to save changes. If the user selects cancel to any of these }
- { options, we need to set the global variable gDone back to FALSE. }
- { }
- { July 15, 1992 WHK Created today }
- { }
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- PROCEDURE CloseDocument(theWindow : WindowPtr);
- BEGIN
- IF ((gDocument = NIL) | (gDocument^^.docWindow = NIL))THEN EXIT(CloseDocument);
-
- DisposeWindow(gDocument^^.docWindow);
-
- DisposHandle(Handle(gDocument));
- gDocument := NIL;
-
- SetMenuBarState;
- END;
-
- {$S Document}
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- { }
- { CloseAllOpenDocuments }
- { }
- { Currently does nothing beyond calling CloseDocument, but is here for support of a }
- { multiple document enviroment. }
- { }
- { July 15, 1992 WHK Created today }
- { }
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- PROCEDURE CloseAllOpenDocuments;
- BEGIN
- IF ((gDocument = NIL) | (gDocument^^.docWindow = NIL))THEN EXIT(CloseAllOpenDocuments);
- CloseDocument(gDocument^^.docWindow);
- END;
-
- {$S Document}
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- { }
- { InvalDocumentScrollBars }
- { }
- { This makes an assumption that the window being passed to it has two scroll bars, }
- { one along the right hand side and the other along the bottom. It invalidates }
- { the area which the scroll bars occupy. }
- { }
- { July 15, 1992 WHK Created today }
- { }
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- PROCEDURE InvalDocumentScrollBars(theWindow : WindowPtr);
- VAR
- ScrollRect : RECT;
- BEGIN
- ScrollRect := theWindow^.portRect;
- ScrollRect.top := ScrollRect.bottom - 15;
- InvalRect(ScrollRect);
- ScrollRect := theWindow^.portRect;
- ScrollRect.left := ScrollRect.right - 15;
- InvalRect(ScrollRect);
- END;
-
- {$S Document}
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- { }
- { HandleDocumentGrow }
- { }
- { Currently the user is moused down in the grow region of your window and the }
- { window is front most. The standard GrowWindow toolbox routine is called. If }
- { the window is resized then the windows scrollbars need to be invalidated. }
- { }
- { July 15, 1992 WHK Created today }
- { }
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- PROCEDURE HandleDocumentGrow(theWindow : WindowPtr;
- downWhere : POINT);
- VAR
- windRect : RECT;
- sizing : LONGINT;
- holdPort : GrafPtr;
- BEGIN
- IF ((gDocument = NIL) | (gDocument^^.docWindow = NIL))THEN EXIT(HandleDocumentGrow);
-
- GetPort(holdPort);
- SetPort(gDocument^^.docWindow);
- SetRect(windRect,200,100,MaxInt, MaxInt);
- sizing := GrowWindow(gDocument^^.docWindow,downWhere, windRect);
- IF sizing > 0 THEN
- BEGIN
- InvalDocumentScrollBars(gDocument^^.docWindow);
- SizeWindow(gDocument^^.docWindow,LoWord(sizing),HiWord(sizing),TRUE);
- InvalDocumentScrollBars(gDocument^^.docWindow);
- END;
- SetPort(holdPort);
- END;
-
- {$S Document}
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- { }
- { HandleDocumentMousedown }
- { }
- { A mousedown occurred in the document. First we need to see if the document is }
- { frontmost. If it isn't. lets bring it to the front. If it is, handle what is }
- { approprate for a mousedown. }
- { }
- { July 15, 1992 WHK Created today }
- { }
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- PROCEDURE HandleDocumentMousedown(theWindow : WindowPtr;
- theEvent : EventRecord);
- VAR
- where : INTEGER;
- BEGIN
- IF ((gDocument = NIL) | (gDocument^^.docWindow = NIL))THEN EXIT(HandleDocumentMousedown);
-
- where := FindWindow(theEvent.where,theWindow);
- END;
-
- {$S Document}
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- { }
- { HandleDocumentKeydown }
- { }
- { A keydown occured when this documents window was frontmost. This document }
- { structure has no need for keydowns, so this routine does nothing. }
- { }
- { July 15, 1992 WHK Created today }
- { }
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- PROCEDURE HandleDocumentKeydown(theWindow : WindowPtr;
- theKey : Char);
- BEGIN
- IF ((gDocument = NIL) | (gDocument^^.docWindow = NIL))THEN EXIT(HandleDocumentKeydown);
-
- END;
-
- {$S Document}
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- { }
- { DrawTheRoad }
- { }
- { We need to draw the intersection world as we know it, two roads, four turn }
- { lanes, and four big patches of green with all the ammenities. Nuff said. }
- { }
- { July 15, 1992 WHK Created today }
- { }
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- PROCEDURE DrawTheRoad;
- VAR
- holdColor : RGBColor;
- workColor : RGBColor;
- tempRect : RECT;
- BEGIN
- Pensize(2,2);
- ForeColor(WhiteColor);
- Moveto(gHRoadLeft, gHRoadTop); { First the edges of the road! }
- Lineto(gVRoadLeft, gHRoadTop);
- Lineto(gVRoadLeft, gVRoadTop);
-
- Moveto(gVRoadRight, gVRoadTop);
- Lineto(gVRoadRight, gHRoadTop);
- Lineto(gHRoadRight, gHRoadTop);
-
- Moveto(gHRoadRight, gHRoadBottom);
- Lineto(gVRoadRight, gHRoadBottom);
- Lineto(gVRoadRight, gVRoadBottom);
-
- Moveto(gVRoadLeft, gVRoadBottom);
- Lineto(gVRoadLeft, gHRoadBottom);
- Lineto(gHRoadLeft, gHRoadBottom);
-
- ForeColor(GreenColor); { Then the grassy corners }
- SetRect(tempRect, gHRoadLeft, gVRoadTop, gVRoadLeft - 2, gHRoadTop);
- PaintRect(tempRect);
- SetRect(tempRect, gVRoadRight + 2, gVRoadTop,gHRoadRight , gHRoadTop);
- PaintRect(tempRect);
- SetRect(tempRect, gHRoadLeft,gHRoadBottom + 2 , gVRoadLeft - 2, gVRoadBottom);
- PaintRect(tempRect);
- SetRect(tempRect, gVRoadRight + 2, gHRoadBottom + 2,gHRoadRight , gVRoadBottom);
- PaintRect(tempRect);
-
- ForeColor(BlackColor); { And the Road itself }
- SetRect(tempRect, gHRoadLeft, gHRoadTop + 2,gHRoadRight , gHRoadBottom);
- FillRect(tempRect, gray);
- SetRect(tempRect, gVRoadLeft, gVRoadTop,gVRoadRight , gVRoadBottom);
- FillRect(tempRect, gray);
-
- ForeColor(YellowColor); { And the lines near the turning lanes. }
- Moveto(gHRoadLeft, gHRoadTop + 20);
- Lineto(gVRoadLeft, gHRoadTop + 20);
- Moveto(gVRoadRight, gHRoadTop + 40);
- Lineto(gHRoadRight, gHRoadTop + 40);
- Moveto(gVRoadLeft + 40, gVRoadTop);
- Lineto(gVRoadLeft + 40, gHRoadTop);
- Moveto(gVRoadLeft + 20, gVRoadBottom);
- Lineto(gVRoadLeft + 20, gHRoadBottom);
-
- ForeColor(WhiteColor); { Now the concrete medians in the Road. }
- SetRect(tempRect, gHRoadLeft - 5, gHRoadTop + 20 , gVRoadLeft - 80, gHRoadBottom - 20);
- PaintRoundRect(tempRect, 10, 10);
- SetRect(tempRect, gVRoadRight + 80, gHRoadTop + 20 , gHRoadRight + 5, gHRoadBottom - 20);
- PaintRoundRect(tempRect, 10, 10);
- SetRect(tempRect, gVRoadLeft + 20, gVRoadTop -5 , gVRoadRight - 20, gHRoadTop - 80);
- PaintRoundRect(tempRect, 10, 10);
- SetRect(tempRect, gVRoadLeft + 20, gHRoadBottom + 80 , gVRoadRight - 20, gVRoadBottom + 5);
- PaintRoundRect(tempRect, 10, 10);
-
- ForeColor(BlackColor); { Now the concrete medians in the Road. }
- DrawTheTraficLight(FALSE);
- END;
-
- {$S Document}
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- { }
- { HandleDocumentUpdate }
- { }
- { The window needs to be updated. Currently the window has no content, with the }
- { exception of scroll bars and a grow icon, so they are drawn. }
- { }
- { July 15, 1992 WHK Created today }
- { }
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- PROCEDURE HandleDocumentUpdate(theWindow : WindowPtr);
- VAR
- holdPort : GrafPtr;
-
- BEGIN
- GetPort(holdPort);
- SetPort(gDocument^^.docWindow);
- BeginUpdate(gDocument^^.docWindow);
-
- EraseRect(gDocument^^.docWindow^.portRect);
-
- DrawTheRoad;
- UpdateAllCars;
-
- EndUpdate(gDocument^^.docWindow);
- SetPort(holdPort);
- END;
-
- {$S Document}
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- { }
- { HandleDocumentActivateEvt }
- { }
- { The document window was either activated or deactivated. We need to determine }
- { which and handle the window appearence approprately }
- { }
- { July 15, 1992 WHK Created today }
- { }
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- PROCEDURE HandleDocumentActivateEvt(theWindow : WindowPtr; theEvent : EventRecord);
- VAR
- activating : BOOLEAN;
- theGrowRect : RECT;
- BEGIN
- SetPort(theWindow);
- activating := (BAnd(theEvent.modifiers, activeFlag) <> 0);
- theGrowRect := theWindow^.portRect;
- theGrowRect.left := theGrowRect.right - 14;
- theGrowRect.top := theGrowRect.bottom - 14;
- InvalRect(theGrowRect);
- END;
-
- {$S Document}
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- { }
- { HandleDocumentApp4Event }
- { }
- { The application has experienced a context switch. If anything special is needed }
- { to be done to the front document, now would be a good time. }
- { }
- { July 15, 1992 WHK Created today }
- { }
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- PROCEDURE HandleDocumentApp4Event(theWindow : WindowPtr; theEvent : EventRecord);
- BEGIN
- END;
-
- {$S Document}
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- { }
- { HandleDocumentEvent }
- { }
- { If an event occurred, and it occurred to the document window, then the event }
- { will be routed through this procedure. }
- { }
- { July 15, 1992 WHK Created today }
- { }
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- PROCEDURE HandleDocumentEvent(theWindow : WindowPtr; theEvent : EventRecord);
- VAR
- key : Char;
- BEGIN
- IF theWindow = NIL THEN EXIT(HandleDocumentEvent);
-
- CASE theEvent.what OF
- mouseDown: HandleDocumentMousedown(theWindow, theEvent);
- keyDown, autoKey:
- BEGIN
- key := CHR(BAnd(theEvent.message, charCodeMask));
- HandleDocumentKeydown(theWindow, key);
- END;
- UpdateEvt: HandleDocumentUpdate(theWindow);
- ActivateEvt: HandleDocumentActivateEvt(theWindow, theEvent);
- App4Evt: HandleDocumentApp4Event(theWindow, theEvent);
- OTHERWISE
- ;
- END;
- END;
-
- {$S Document}
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- { }
- { IsWindowADocument }
- { }
- { Given a window pointer, this routine reports when the window is a document. The }
- { reason for handling window verification this way is to add flexibility so that }
- { this application can support multple documents in the future. }
- { }
- { July 15, 1992 WHK Created today }
- { }
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- FUNCTION IsWindowADocument(theWind : WindowPtr) : BOOLEAN;
- BEGIN
- IsWindowADocument := FALSE;
- IF ((gDocument = NIL) | (gDocument^^.docWindow = NIL))THEN EXIT(IsWindowADocument);
-
- IsWindowADocument := (theWind = gDocument^^.docWindow);
- END;
-
- {$S Document}
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- { }
- { DoPrintDocument }
- { }
- { Given a window pointer,find the document that is associated with it and print it. }
- { }
- { July 15, 1992 WHK Created today }
- { }
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- PROCEDURE DoPrintDocument(theWind : WindowPtr);
- BEGIN
- { I have not yet implemented document printing yet! - WHK }
- END;
-
- {$S Document}
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- { }
- { DoPrintDocument }
- { }
- { Given a window pointer, find the document that is associated with it and print it }
- { }
- { July 15, 1992 WHK Created today }
- { }
- {––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––-––}
- PROCEDURE DoPageSetupDoc(theWind : WindowPtr);
- BEGIN
- { I have not yet implemented document printing yet! - WHK }
- END;
-
- END.